﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tomahawk.Runtime.Serialization;
using System.Xml.Serialization;
using Tomahawk.Runtime.Resources;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using System.IO;

namespace Tomahawk.Runtime.Rendering.Materials
{
    #region SASMaterialTemplateParameter
    [XmlInclude(typeof(SASMaterialTemplateBoolParameter))]
    [XmlInclude(typeof(SASMaterialTemplateIntParameter))]
    [XmlInclude(typeof(SASMaterialTemplateFloatParameter))]
    [XmlInclude(typeof(SASMaterialTemplateStringParameter))]
    [XmlInclude(typeof(SASMaterialTemplateVectorParameter))]
    [XmlInclude(typeof(SASMaterialTemplateTextureParameter))]
    public abstract class SASMaterialTemplateParameter
    {
        [XmlAttribute("Name")]
        public string name = "Undefined";

        public abstract bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager);
    }

    public class SASMaterialTemplateBoolParameter : SASMaterialTemplateParameter
    {
        [XmlAttribute("Value")]
        public bool value = false;

        public override bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager)
        {
            bool result = true;
            SASParameter parameter = effect.Parameters[name];
            parameter.BoolValue = value;
            return result;
        }
    }

    public class SASMaterialTemplateIntParameter : SASMaterialTemplateParameter
    {
        [XmlAttribute("Value")]
        public int value = 0;

        public override bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager)
        {
            bool result = true;
            SASParameter parameter = effect.Parameters[name];
            parameter.IntValue = value;
            return result;
        }
    }

    public class SASMaterialTemplateFloatParameter : SASMaterialTemplateParameter
    {
        [XmlAttribute("Value")]
        public float value = 0.0f;

        public override bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager)
        {
            bool result = true;
            SASParameter parameter = effect.Parameters[name];
            parameter.FloatValue = value;
            return result;
        }
    }

    public class SASMaterialTemplateStringParameter : SASMaterialTemplateParameter
    {
        [XmlAttribute("Value")]
        public string value = "Undefined";

        public override bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager)
        {
            bool result = true;
            SASParameter parameter = effect.Parameters[name];
            parameter.StringValue = value;
            return result;
        }
    }

    public class SASMaterialTemplateVectorParameter : SASMaterialTemplateParameter
    {
        [XmlElement("Value")]
        public Vector4 value = Vector4.Zero;

        public override bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager)
        {
            bool result = true;
            SASParameter parameter = effect.Parameters[name];
            parameter.VectorValue = value;
            return result;
        }
    }

    public class SASMaterialTemplateTextureParameter : SASMaterialTemplateParameter
    {
        [XmlAttribute("Value")]
        public string value = "Undefined";

        public override bool Initialize(SASEffect effect, string rootPath, ContentManager contentManager)
        {
            bool result = true;
            SASParameter parameter = effect.Parameters[name];
            parameter.TextureValue = contentManager.Load<Texture>(Path.Combine(rootPath,value));
            return result;
        }
    }
    #endregion

    #region SASMaterialTemplate
    public class SASEffectTemplate
    {
        [XmlAttribute("Name")]
        public string name;

        [XmlAttribute("EffectName")]
        public string effectName = "Undefined";

        public SerializableList<SASMaterialTemplateParameter> parameters = new SerializableList<SASMaterialTemplateParameter>();

        public T Build<T>(string rootPath, ContentManager contentManager) where T : SASEffect, new()
        {
            string effectFile = Path.Combine(rootPath, effectName);

            T sasEffect = new T();
            sasEffect.Initialize(effectFile, contentManager);

            foreach (SASMaterialTemplateParameter parameter in parameters)
            {
                parameter.Initialize(sasEffect, rootPath, contentManager);
            }

            return sasEffect;
        }
    }
    #endregion
}
